Diferença entre: char *argv[] e char argc[]

13. Re: Diferença entre: char *argv[] e char argc[]

Perfil removido
removido

(usa Nenhuma)

Enviado em 20/08/2012 - 05:50h

paulo1205 escreveu:

Só há um problema: estamos falando da função main() que usa uma variável que recebe um valor inteiro. Se vocẽ quiser usar essa execve que conta os parâmetros ao invés, aí é outra história ... :-P A exemplo do último parâmetro de main() pode ser acessada com uma função sem usar o parâmetro. Falei sobre isso lá atrás.

OBS: Faltou explicar a função assert() :-P


Hein?

A chamada execve() não é uma alternativa a main(), mas sim a chamada que faz com que o kernel execute um programa novo.

Por exemplo, quando você digita no shell um comando como

expr 23 + 45 


o que o shell vai fazer é contar quantos são os componentes da linha de comando (4 strings, que no nosso exemplo são "expr", "23", "+" e "45"), alocar espaço na memória para 5 (i.e. 4+1) ponteiros de caracteres, aos quais ele vai atribuir os endereços das 4 strings e, no fim, um ponteiro nulo), descobrir um qual diretório do PATH reside o comando "expr", e executar esse programa. Em algum momento do tempo, ter-se-á executado alguma coisa funcionalmente equivalente a tudo o que vai abaixo.

extern char **environ; /* array com as variáveis de ambiente do processo */
char *executavel, **argumentos;
int nargs;

nargs=4;
argumentos=malloc((1+nargs)*sizeof(char *));
argumentos[0]="expr";
argumentos[1]="23";
argumentos[2]="+";
argumentos[3]="45";
argumentos[nargs]=NULL;
executavel="/usr/bin/expr";

execve(executavel, argumentos, environ);


Admitindo que o comando expr tenha sido escrito em C (e realmente foi!), sua função main() terá sido escrita na forma int main(int argc, char **argv). Quando ele for disparado pelo execve() mostrado acima, argc terá o valor 4, indicando que há em argv quatro elementos aproveitáveis (índices 0 a argc-1, que é 3, do array, portanto).

Eu digo, porém, que o tamanho real do array argv não é 4, mas 5, porque haverá (ao menos no Linux) um ponteiro nulo lodo após o último elemento "aproveitável". Esse ponteiro nulo poderia ser usado para descobrir o final da lista de argumentos sem consultar o valor de argc -- ao contrário do que você sugeriu ao dizer que usar argc é a única forma de percorrer argv.


Quanto a assert(), a manpage lhe dirá que é uma função que aborta o programa caso a condição testada seja falsa. Eu a usei no exemplo que mostrei só para deixar claro que o programa não será abortado se acaso resolver verificar se argv[argc] é realmente nulo ou não.


Mencionei assert() porque pareceu-me tão contextualizada quanto execve(). Mas você tem razão: relendo agora vi que confundi o número de parâmetros com o tamanho do vetor.




  


14. Re: Diferença entre: char *argv[] e char argc[]

Perfil removido
removido

(usa Nenhuma)

Enviado em 06/09/2012 - 12:09h

Li apenas por cima o que a galera respondeu, mas tentando simplificar (desculpa se alguém já comentou)


char *argv[] poderia ser escrito como char **argv



> Temos uma cadeia de caracteres, que é um ponteiro
> E depois temos ponteiros apontando para essas cadeiras de caracteres



01 02



Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts